package com.huige.wiki.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器：用于登录校验
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(LoginInterceptor.class);

    @Resource(name = "stringRedisTemplate")
    private StringRedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法，直接放行
            return true;
        }

        // OPTIONS请求不做校验
        // 前后端分离架构，前端会发一个OPTIONS请求先做预检，对预检请求不做校验
        //户端可以使用 OPTIONS 请求来确定服务器支持哪些 HTTP 方法（如 GET、POST、PUT、DELETE 等）以及服务器允许的其他功能。
        // 通常，OPTIONS 请求用于跨域资源共享（CORS）预检请求，以检查服务器是否允许特定的跨域请求。
        if(request.getMethod().toUpperCase().equals("OPTIONS")){
            return true;
        }

        String path = request.getRequestURL().toString();
        LOG.info("接口拦截路径为{}",path);

        // 获取header的token参数
        String token = request.getHeader("token");
        LOG.info("登录校验开始token:{}",token);
        if(token==null || token.isEmpty()){
            LOG.info("token为空，请求被拦截");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        Object object = redisTemplate.opsForValue().get(token);
        if(object==null){
            LOG.warn("token无效，请求被拦截");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }else{
            LOG.info("已登录：{}",object);
            return true;
        }


    }
}
